﻿using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using ESoft.Helpers;

namespace ESoft.Extensions {

    /// <summary>
    /// 类型转换扩展
    /// </summary>
    public static partial class Extension {

        #region 转换为byte

        /// <summary>
        /// 转换为byte
        /// </summary>
        /// <param name="obj">数据</param>
        public static byte ToByte(this string obj) {
            return ConvertHelper.ToByte(obj);
        }

        /// <summary>
        /// 转换为可空byte
        /// </summary>
        /// <param name="obj">数据</param>
        public static byte? ToByteOrNull(this string obj) {
            return ConvertHelper.ToByteOrNull(obj);
        }

        /// <summary>
        /// 转换为byte
        /// </summary>
        /// <param name="obj">数据</param>
        public static byte ToByte(this int obj) {
            return ConvertHelper.ToByte(obj);
        }

        #endregion 转换为byte

        #region 转换为int

        /// <summary>
        /// 转换为int
        /// </summary>
        /// <param name="obj">数据</param>
        public static int ToInt(this string obj) {
            return ConvertHelper.ToInt(obj);
        }

        /// <summary>
        /// 转换为int，小于0返回0，否则返回原int值
        /// </summary>
        /// <param name="obj">数据</param>
        public static int ToInt0(this string obj) {
            return ConvertHelper.ToInt0(obj);
        }

        /// <summary>
        /// 转换为int，小于1返回1，否则返回原int值
        /// </summary>
        /// <param name="obj">数据</param>
        public static int ToInt1(this string obj) {
            return ConvertHelper.ToInt1(obj);
        }

        /// <summary>
        /// 转换为可空int
        /// </summary>
        /// <param name="obj">数据</param>
        public static int? ToIntOrNull(this string obj) {
            return ConvertHelper.ToIntOrNull(obj);
        }

        #endregion 转换为int

        #region 转换为long

        /// <summary>
        /// 转换为int
        /// </summary>
        /// <param name="obj">数据</param>
        public static long ToLong(this string obj) {
            return ConvertHelper.ToLong(obj);
        }

        /// <summary>
        /// 转换为int，小于0返回0，否则返回原int值
        /// </summary>
        /// <param name="obj">数据</param>
        public static long ToLong0(this string obj) {
            return ConvertHelper.ToLong0(obj);
        }

        /// <summary>
        /// 转换为int，小于1返回1，否则返回原int值
        /// </summary>
        /// <param name="obj">数据</param>
        public static long ToLong1(this string obj) {
            return ConvertHelper.ToLong1(obj);
        }

        /// <summary>
        /// 转换为可空int
        /// </summary>
        /// <param name="obj">数据</param>
        public static long? ToLongOrNull(this string obj) {
            return ConvertHelper.ToLongOrNull(obj);
        }

        #endregion 转换为long

        #region 转换为double

        /// <summary>
        /// 转换为double
        /// </summary>
        /// <param name="obj">数据</param>
        public static double ToDouble(this string obj) {
            return ConvertHelper.ToDouble(obj);
        }

        /// <summary>
        /// 转换为double，小于0返回0，否则返回原double值
        /// </summary>
        /// <param name="obj">数据</param>
        public static double ToDouble0(this string obj) {
            return ConvertHelper.ToDouble0(obj);
        }

        /// <summary>
        /// 转换为double，小于1返回1，否则返回原double值
        /// </summary>
        /// <param name="obj">数据</param>
        public static double ToDouble1(this string obj) {
            return ConvertHelper.ToDouble1(obj);
        }

        /// <summary>
        /// 转换为可空double
        /// </summary>
        /// <param name="obj">数据</param>
        public static double? ToDoubleOrNull(this string obj) {
            return ConvertHelper.ToDoubleOrNull(obj);
        }

        #endregion 转换为double

        #region 转换为decimal

        /// <summary>
        /// 转换为decimal
        /// </summary>
        /// <param name="obj">数据</param>
        public static decimal ToDecimal(this string obj) {
            return ConvertHelper.ToDecimal(obj);
        }

        /// <summary>
        /// 转换为decimal，小于0返回0，否则返回原decimal值
        /// </summary>
        /// <param name="obj">数据</param>
        public static decimal ToDecimal0(this string obj) {
            return ConvertHelper.ToDecimal0(obj);
        }

        /// <summary>
        /// 转换为decimal，小于1返回1，否则返回原decimal值
        /// </summary>
        /// <param name="obj">数据</param>
        public static decimal ToDecimal1(this string obj) {
            return ConvertHelper.ToDecimal1(obj);
        }

        /// <summary>
        /// 转换为可空decimal
        /// </summary>
        /// <param name="obj">数据</param>
        public static decimal? ToDecimalOrNull(this string obj) {
            return ConvertHelper.ToDecimalOrNull(obj);
        }

        #endregion 转换为decimal

        #region 转换为日期

        /// <summary>
        /// 转换为日期（yyyy-MM-dd）
        /// </summary>
        /// <param name="obj">数据</param>
        public static DateTime ToDate(this string obj) {
            return ConvertHelper.ToDate(obj).Date;
        }

        /// <summary>
        /// 转换为日期（yyyy-MM-dd HH:mm:ss）
        /// </summary>
        /// <param name="obj">数据</param>
        public static DateTime ToDateTime(this string obj) {
            return ConvertHelper.ToDate(obj);
        }

        /// <summary>
        /// 转换为可空日期
        /// </summary>
        /// <param name="obj">数据</param>
        public static DateTime? ToDateOrNull(this string obj) {
            return ConvertHelper.ToDateOrNull(obj);
        }

        #endregion 转换为日期

        #region 转换字符串

        /// <summary>
        /// 转换字符串，并去除两边空格
        /// </summary>
        /// <param name="obj">对象</param>
        public static string ToStr(this object obj) {
            return ConvertHelper.ToString(obj);
        }

        #endregion 转换字符串

        #region MD5
        public static string Md5(this string str) {
            using var md5 = MD5.Create();
            var result = md5.ComputeHash(Encoding.UTF8.GetBytes(str));
            var strResult = BitConverter.ToString(result);

            return strResult.Replace("-", "");
        }
        #endregion

        #region image
        /// <summary>
        /// Image 转成 base64
        /// </summary>
        /// <param name="fileFullName"></param>
        public static string ImageToBase64(this string fileFullName) {
            try {
                var bmp = new Bitmap(fileFullName);
                using var ms = new MemoryStream();
                var suffix = fileFullName.Substring(fileFullName.LastIndexOf('.') + 1,
                    fileFullName.Length - fileFullName.LastIndexOf('.') - 1).ToLower();
                //var suffixName = 
                //    suffix == "png" ? ImageFormat.Png : 
                //        suffix == "jpg" || suffix == "jpeg" ? ImageFormat.Jpeg : suffix == "bmp" ? ImageFormat.Bmp : suffix == "gif" ? ImageFormat.Gif : ImageFormat.Jpeg;


                ImageFormat suffixName;
                switch (suffix) {
                    case "png":
                        suffixName = ImageFormat.Png;
                        break;
                    case "jpg":
                    case "jpeg":
                        suffixName = ImageFormat.Jpeg;
                        break;
                    case "bmp":
                        suffixName = ImageFormat.Bmp;
                        break;
                    case "gif":
                        suffixName = ImageFormat.Gif;
                        break;
                    default:
                        suffixName = ImageFormat.Jpeg;
                        break;
                }

                bmp.Save(ms, suffixName);
                var arr = new byte[ms.Length]; ms.Position = 0;
                ms.Read(arr, 0, (int)ms.Length); ms.Close();

                return Convert.ToBase64String(arr);
            }
            catch {
                return string.Empty;
            }
        }

        public static byte[] ImageToByte(this Image image, ImageFormat imgFormat) {
            if (image == null) throw new ArgumentException(nameof(image));

            using var ms = new MemoryStream();

            image.Save(ms, imgFormat);
            var bytes = ms.GetBuffer();
            ms.Close();

            return bytes;
        }
        #endregion

        public static string StreamToBase64(this Stream stream) {
           
            var arr = new byte[stream.Length];
            stream.Read(arr, 0, arr.Length);
            // 设置当前流的位置为流的开始 
            stream.Seek(0, SeekOrigin.Begin);

            string base64 = Convert.ToBase64String(arr);

            return base64;
        }

        /*
        public static MemoryStream StreamToMemoryStream(this Stream stream) {
            var ms = new MemoryStream();
            const int bufferLen = 4096;
            byte[] buffer = new byte[stream.Length];
            int count;
            while ((count = stream.Read(buffer, 0, bufferLen)) > 0) {
                ms.Write(buffer, 0, count);
            }

            return ms;
        }
        */

        #region PadLeft
        public static string PadLeft4(this string str) {
            return str.MyPadLeft(4, '0');
        }

        public static string PadLeft3(this string str) {
            return str.MyPadLeft(3, '0');
        }

        private static string MyPadLeft(this string str, int length, char paddingChar) {

            if (length <= 0) return str;
            return str.PadLeft(length, paddingChar);
        }
        #endregion

        #region IdsToArray

        //public static long[] IdsToArray(this string ids, string separator = ",") {
        //    if (ids.IsEmpty()) return new long[0];

        //    ids = StringHelper.FixIdList(ids, separator);
        //    var arr = ids.Split(separator);
        //    if (arr.Length > 0) {
        //        return Array.ConvertAll(arr, ConvertHelper.ToLong0);
        //    }

        //    return new long[0];
        //}

        #endregion Arrary 


    }
}